#pragma once

class INode;
struct GLShader;

struct ESceneInstanceContainerFlag
{
	enum Type
	{
	    Ignore				= 1 << 0
	};
};

/*--------------------------------------------------------------------------*/

struct SceneInstanceContainer
{
	SceneInstance*	m_sceneInstance;
	uint	m_flags;

	SceneInstanceContainer() :
		m_sceneInstance(NULL),
		m_flags(0)
	{}
};

/*--------------------------------------------------------------------------*/

struct EFreeCameraMovementFlag
{
	enum Flag
	{
	    MoveForward			= 1 << 0,
	    MoveBackward		= 1 << 1,
	    MoveLeft			= 1 << 2,
	    MoveRight			= 1 << 3,
	    MoveUp				= 1 << 4,
	    MoveDown			= 1 << 5,
	    RotateForward		= 1 << 6,
	    RotateBackward		= 1 << 7,
	    RotateLeft			= 1 << 8,
	    RotateRight			= 1 << 9,
	    RotateUp			= 1 << 10,
	    RotateDown			= 1 << 11,
	    UseMouse			= 1 << 12
	};
};

/*--------------------------------------------------------------------------*/

class CScene final :
	public IEngMod,
	public ICalc,
	public ICriticalSection,
	public IKeyboardDriver
{
public:
	CScene();
	~CScene();

	/*-ICalc--------------------------------------------------------------------*/
	virtual void OnCalc(uint arg) override;

	/*-IKeyboardDriver----------------------------------------------------------*/
	virtual void			OnKeyboardAction() override;

	/*--------------------------------------------------------------------------*/

	void					SetFreeCamera(PerspectiveCamera* camera);
	PerspectiveCamera*		GetFreeCamera() const;

	SceneInstance*			CreateScene();
	void					DeleteScene(SceneInstance* scene);
	void					SetSceneFlags(SceneInstance* scene, uint flags);

private:
	/*--------------------------------------------------------------------------*/
	SceneInstanceContainer& GetSceneInstanceContainer(SceneInstance* scene);

	std::vector<SceneInstanceContainer> m_sceneInstances;
	PerspectiveCamera*		m_freeCamera;
	uint					m_freeCameraInput;
	void					UpdateFreeCamera();
	Variable*				var_fcamera_enabled;
	Variable*				var_fcamera_movement_speed;
	Variable*				var_fcamera_rotation_speed;
};

namespace sh
{
void				setfcampos(float x, float y, float z);
void				setfcamrot(float x, float y, float z);
void				fcamdebug();
const glm::vec3&	getfcampos();
};

extern CScene* g_Scene;